package org.tuestudent.grouppa;

import org.tuestudent.grouppa.AppContext.ActiveScreens;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.Image;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;

public class Login extends Activity {

    // declaration and initialization of variables
    String loginEmail;
    String loginPin;
    String forgotEmail;
    String createEmail;
    String nickName;
    String createPin;
    String verifyPin;
    boolean check;
    LoginViewController LC = LoginViewController.getInstance();
    ProgressDialog currentProgressDialog = null;
    AlertDialog currentAlertDialog = null;

    // Method to turn off possible pending dialogs
    public void turnOffDialogs() {
        if (currentProgressDialog != null && currentProgressDialog.isShowing()) {
            currentProgressDialog.dismiss();
        }
        if (currentAlertDialog != null && currentAlertDialog.isShowing()) {
            currentAlertDialog.dismiss();
        }
    }

    /**
     * creates the forgot password button
     */
    public void forgotPasswordPopup(View view) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        // Get the layout inflater
        LayoutInflater inflater = this.getLayoutInflater();

        // Inflate and set the layout for the dialog
        // Pass null as the parent view because its going in the dialog layout
        builder.setView(inflater.inflate(R.layout.popup_forgot_password, null));
        // create the popup (alert dialog)
        final AlertDialog forgotPinPopup = builder.create();
        // make the popup visible
        forgotPinPopup.show();
        // add a listener to the button of the popup so it can do something when
        // pressed on
        Button sendPassword =
                (Button) forgotPinPopup.findViewById(R.id.send_password);
        sendPassword.setOnClickListener(new OnClickListener() {

            // declare what to do when the button is pressed
            @Override
            public void onClick(View arg0) {
                // get the text of the edittext field with id username
                forgotEmail =
                        ((EditText) forgotPinPopup.findViewById(R.id.username))
                                .getText().toString();
                // check if the email is of the proper form
                if (emailIsValid(forgotEmail)) {
                    // if it is dismiss the popup and send the password to the
                    // email
                    forgotPinPopup.dismiss();

                    LC.resetPassword(forgotEmail);

                    turnOffDialogs();
                    // TODO: show a message with "processing..." or smth like
                    // this
                    passwordSentPopup();
                } else {
                    // if the email is not valid give an error
                    ((EditText) forgotPinPopup.findViewById(R.id.username))
                            .setError("Please enter a valid email");
                }
            }
        });
        // TODO:create close button
        ImageButton cancel = (ImageButton) forgotPinPopup.findViewById(R.id.cancelButton);
        cancel.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                forgotPinPopup.dismiss();
            }
        });
    }

    /**
     * open a popup to confirm the password is sent
     */
    private void passwordSentPopup() {
        // TODO:Create popup
        // TODO:Create 'OK' button to confirm and close the popup
    }


    /**
     * creates the create account popup
     */
    public void createAccountPopup(View view) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        // Get the layout inflater
        LayoutInflater inflater = this.getLayoutInflater();

        // Inflate and set the layout for the dialog
        // Pass null as the parent view because its going in the dialog layout
        builder.setView(inflater.inflate(R.layout.popup_create_account, null));
        // create the popup
        final AlertDialog createAccountPopup = builder.create();
        // show the popup
        createAccountPopup.show();
        // add a listener to the button of the popup
        Button createAccountButton =
                (Button) createAccountPopup.findViewById(R.id.create_account);
        createAccountButton.setOnClickListener(new OnClickListener() {

            // declare what the button should do when pressed
            @Override
            public void onClick(View arg0) {
                // get the input of the fields
                createEmail =
                        ((EditText) createAccountPopup
                                .findViewById(R.id.username)).getText()
                                .toString();
                nickName =
                        ((EditText) createAccountPopup
                                .findViewById(R.id.userInfoNickname)).getText()
                                .toString();
                createPin =
                        ((EditText) createAccountPopup
                                .findViewById(R.id.setPassword)).getText()
                                .toString();
                verifyPin =
                        ((EditText) createAccountPopup
                                .findViewById(R.id.confirmPassword)).getText()
                                .toString();
                // check if all fields contain valid information before creating
                // the account
                check = true;
                
             // check if the email is valid
                if ( !emailIsValid(createEmail)) {
                    ((EditText) createAccountPopup.findViewById(R.id.username))
                            .setError("Please enter a valid email");
                    check = false;
                }
                // check if there is a nickname filled in
                else if (nickName.trim().isEmpty()) {
                    ((EditText) createAccountPopup.findViewById(R.id.userInfoNickname))
                            .setError("Please enter a nickname");
                    check = false;
                }
                else if (nickName.equals("you")){
                    ((EditText) createAccountPopup.findViewById(R.id.userInfoNickname))
                    .setError("Your nickname may not be 'you'");
                    check = false;
                }
                // check if the nickname contains only valid characters
                else if (!isValid(nickName)) {
                    ((EditText) createAccountPopup.findViewById(R.id.userInfoNickname))
                            .setError("nickname may only containt (a-z, A-Z, 0-9)");
                    check = false;
                }
                
                // check if the pin field is not empty
                else if (createPin.isEmpty()) {
                    ((EditText) createAccountPopup.findViewById(R.id.setPassword))
                            .setError("Please choose a pincode");
                    check = false;
                }
                // check if the pin field contains 4 digits
                else if (createPin.length() < 4) {
                    ((EditText) createAccountPopup.findViewById(R.id.setPassword))
                            .setError("Pincode should contain 4 digits");
                    check = false;
                }
                // check if the verification pin matches the other pin
                else if ( !createPin.equals(verifyPin)) {
                    ((EditText) createAccountPopup
                            .findViewById(R.id.confirmPassword))
                            .setError("this does not match the pincode above");
                    check = false;
                }
                
                // create the account if all tests are passed
                if (check) {
                    createAccountPopup.dismiss();
                    turnOffDialogs();
                    currentProgressDialog =
                            ProgressDialog
                                    .show(Login.this,
                                            "",
                                            "Your account is being created, please wait...",
                                            true);
                    LC.createAccount(nickName, createPin, createEmail);
                    // CHECK: show a message with "processing..." or smth like
                    // this
                    // dialog.dismiss();
                }
            }
        });
        
//      cancel button for the account creation
        final ImageButton cancel = (ImageButton) createAccountPopup.findViewById(R.id.cancelButton);
        cancel.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                createAccountPopup.dismiss();
            }
        });
    }

    /**
     * logs the in user
     * 
     * @param loginEmail
     *            the email of the user
     * @param loginPassword
     *            the password of the user
     */

    public void loginUser(View view) {
        check = true;
        // get the input of the user
        loginEmail =
                ((EditText) this.findViewById(R.id.login_email)).getText()
                        .toString();
        loginPin =
                ((EditText) this.findViewById(R.id.login_pin)).getText()
                        .toString();
        // check if the pin field is not empty
        if (loginPin.isEmpty()) {
            check = false;
            ((EditText) this.findViewById(R.id.login_pin))
                    .setError("Please enter your pin");
        }
        // check if the pin contains 4 digits
        if (loginPin.length() < 4) {
            check = false;
            ((EditText) this.findViewById(R.id.login_pin))
                    .setError("Please enter a valid pin");
        }
        // check if the email is of the right form
        if ( !emailIsValid(loginEmail)) {
            ((EditText) this.findViewById(R.id.login_email))
                    .setError("Please enter a valid Email");
            check = false;
        }
        if (check) {
            turnOffDialogs();
            currentProgressDialog =
                    ProgressDialog.show(Login.this, "",
                            "You are being logged in, please wait...", true);
            LC.login(loginEmail, loginPin);
            // CHECK: show a message with "processing..." or smth like this
        }
        // comment such that the app will ask for valid credentials
        // startActivity(new Intent(this, GrouppaScreen.class));
    }

    public void onLoginResponse(LoginViewController.LoginResponse response) {
        // CHECK: turn off waiting message
        turnOffDialogs();
        if (response.succeeded) {
            startActivity(new Intent(this, GrouppaScreen.class));
        } else {
            // CHECK: if not logged in, show why
            errorPopup(response.errorReason);
        }
    }

    public void onCreateAccountResponse(
            LoginViewController.CreateAccountResponse response) {
        turnOffDialogs();
        // CHECK: turn off waiting message
        if (response.succeeded) {
            currentProgressDialog =
                    ProgressDialog
                            .show(Login.this,
                                    "",
                                    "Account successfully created. " +
                                    "You are being logged in, please wait...",
                                    true);
            LC.login(createEmail, createPin);
        } else {
            errorPopup(response.errorReason);
        }
    }

    public void onResetPasswordResponse(
            LoginViewController.ResetPasswordResponse response) {
        turnOffDialogs();
        if (response.succeeded) {
            errorPopup("Your pincode has been sent to your email");
        } else {
            errorPopup(response.errorReason);
        }
    }

    /**
     * Method showing the error message when an error occurs
     * 
     * @param errorMessage
     */
    public void errorPopup(String errorMessage) {
        turnOffDialogs();
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(errorMessage);
        builder.setTitle("Error");
        android.content.DialogInterface.OnClickListener closer =
                new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        turnOffDialogs();

                    }
                };
        builder.setPositiveButton("OK", closer);
        currentAlertDialog = builder.create();
        currentAlertDialog.show();
    }

    // method to check if an email is not empty and of the right form
    public boolean emailIsValid(String email) {
        return !email.isEmpty()
                && email.matches("[a-zA-Z0-9\\-\\_\\.]+@[a-zA-Z0-9\\-\\_\\.]+\\.[a-zA-Z0-9]{2,3}");
    }

    // method to check if a nickname contains only (capital) letters and numbers
    public boolean isValid(String name) {
        return name.matches("[a-zA-Z0-9 ]+");
    }

    @Override
    // method that hides the keyboard when pressed outside the
            public boolean onTouchEvent(MotionEvent event) {

        hideSoftKeyboard(Login.this);

        return false;
    }

    public static void hideSoftKeyboard(Activity activity) {

        InputMethodManager im =
                (InputMethodManager) activity
                        .getSystemService(Activity.INPUT_METHOD_SERVICE);
        im.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(),
                0);
    }

    // ----------------Login Activity-------------------
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        EditText pin = (EditText) this.findViewById(R.id.login_pin);
        pin.setOnKeyListener(new OnKeyListener() {
            public boolean onEditorAction(View view, int press, KeyEvent event) {
              
                if ( (event.getAction() == KeyEvent.ACTION_DOWN ) &&
                        (press == KeyEvent.KEYCODE_ENTER) )
                        { 
                            loginUser(view);
                            return true;
                    }
                
                return false;
            }

            @Override
            public boolean onKey(View view, int press, KeyEvent event) {
                if ( (event.getAction() == KeyEvent.ACTION_DOWN ) &&
                        (press == KeyEvent.KEYCODE_ENTER) )
                        { 
                            loginUser(view);
                            return true;
                    }
                return false;
            }
        });
        if (savedInstanceState == null) {
            
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        Main.initializeApp();
        AppContext ctx = Main.getContext();
        ctx.loginActivity = this;
        ctx.activeScreen = ActiveScreens.login;
        ctx.setCurrentViewController(LoginViewController.getInstance());
    }
    

    /**
     * shows an connection error message with ability to cancel reconnection
     * 
     * @param errorMessage
     *            text to show inside error message
     */
    public void connectionErrorPopup(String errorMessage) {
        turnOffDialogs();
        android.content.DialogInterface.OnClickListener closer =
                new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        turnOffDialogs();
                        Main.getConnection().retry = false;
                        
                    }
                };

        currentProgressDialog = new ProgressDialog(this);
        currentProgressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", closer);
        currentProgressDialog.setTitle("Connection error");
        currentProgressDialog.setMessage(errorMessage);
        currentProgressDialog.show();
    }
}